﻿using System;
using System.Collections.Generic;
using System.Text;
using Vortex.Wrapper.Direct3D;
using Vortex.Wrapper;
using Vortex.Debugging;

namespace Vortex.Drawing {
	/// <summary>
	/// Pixel shader object. Stateful, contains shader params
	/// </summary>
	public class VertexShader : Shader {
		private Direct3DVertexShader9 _shader;

		#region Constructors
		/// <summary>
		/// Initializes a new instance of the <see cref="VertexShader"/> class.
		/// </summary>
		/// <param name="fileName">Name of the file with shader code.</param>
		/// <param name="profile">The vertex shader compilation profile.</param>
        /// <param name="entryPoint">The name of entry point function for this shader.</param>
        public VertexShader(string fileName, VertexShaderProfile profile, string entryPoint) {
            using (D3DXBuffer shaderBytes = CompileFromFile(fileName, MakeProfileString(profile), entryPoint)) {
                unsafe {
                    HResult result = Device.ApiRef.CreateVertexShader(shaderBytes.GetBufferPointer(), out _shader);
                    Watcher.AssertCritical(result, "Create vertex shader from file: '{0}', profile: {1}, entryPoint: {2}", fileName, profile, entryPoint);
                }
            }
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="VertexShader"/> class. Entry point - default.
		/// </summary>
		/// <param name="fileName">Name of the file with shader code.</param>
		/// <param name="profile">The vs profile.</param>
		public VertexShader(string fileName, VertexShaderProfile profile) :
			this(fileName, profile, DefaultEntryPoint){
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="VertexShader"/> class. Profile - default.
		/// </summary>
		/// <param name="fileName">Name of the file with shader code.</param>
		/// <param name="entryPoint">The entry point fn name.</param>
		public VertexShader(string fileName, string entryPoint) :
			this(fileName, DefaultProfile, entryPoint) {
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="VertexShader"/> class. Profile and entry point are default.
		/// </summary>
		/// <param name="fileName">Name of the file with shader code.</param>
		public VertexShader(string fileName) :
			this(fileName, DefaultProfile, DefaultEntryPoint) {
		}

		#endregion

		/// <summary>
		/// Gets the shader wrapper object.
		/// </summary>
		/// <value>The wrapper object.</value>
		internal Direct3DVertexShader9 Handle {
			get { return _shader; }
		}

		/// <summary>
		/// Converts the vertex shader profile into  string.
		/// </summary>
		/// <param name="profile">The ps profile.</param>
		/// <returns>String representation of profile</returns>
		private static string MakeProfileString(VertexShaderProfile profile) {
			int value = (int)profile;
			return string.Format("vs_{0}_{1}", (value >> 16), (value & 0xFFFF));
		}

		/// <summary>
		/// Frees the internal data of shader.
		/// </summary>
		protected override void FreeData() {
			_shader.Dispose();
			base.FreeData();
		}

		/// <summary>
		/// Gets the default entry point for vertex shader.
		/// </summary>
		/// <value>The default entry point name.</value>
		public static string DefaultEntryPoint {
			get { return "vs_main"; }
		}

		/// <summary>
		/// Gets the default profile for vertex shader.
		/// </summary>
		/// <value>The ps profile.</value>
		public static VertexShaderProfile DefaultProfile {
			get { return VertexShaderProfile.Vs_2_0; }
		}

		/// <summary>Default vertex shader instance</summary>
		public static readonly VertexShader Default = null;

	}
}
